using System;
using System.Collections.Generic;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Test.BO.TestUtils;
using FireStarterModeller.Test;
using Habanero.Testability;
using NUnit.Framework;
namespace Firestarter.DB.Schema.Test.BO
{
    [TestFixture]
    public partial class TestDBPrimaryKey
    {
        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = TestUtilsDBPrimaryKey.CreateUnsavedValidDBPrimaryKey();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string actualToString = dbPrimaryKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dbPrimaryKey.Table.TableName + " - Primary", actualToString);
        }
        [Test]
        public void Test_ToString_TableIsNull()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = TestUtilsDBPrimaryKey.CreateUnsavedValidDBPrimaryKey();
            dbPrimaryKey.Table = null;
            //---------------Assert Precondition----------------
            Assert.IsNull(dbPrimaryKey.Table);
            //---------------Execute Test ----------------------
            string actualToString = dbPrimaryKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(" - Primary", actualToString);
        }
        [Test]
        public void Test_ToString_HasColumn()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = TestUtilsDBPrimaryKey.CreateUnsavedValidDBPrimaryKey();
            DBColumn column = TestUtilsDBColumn.CreateUnsavedValidDBColumn();
            dbPrimaryKey.AddColumnInfo(column);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dbPrimaryKey.Columns.Count);
            //---------------Execute Test ----------------------
            string actualToString = dbPrimaryKey.ToString();
            //---------------Test Result -----------------------
            string expectedToString = dbPrimaryKey.Table.TableName + " - Primary (" + column.ColumnName +")";
            Assert.AreEqual(expectedToString, actualToString);
        }
        [Test]
        public void Test_ToString_HasTwoColumns()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = TestUtilsDBPrimaryKey.CreateUnsavedValidDBPrimaryKey();
            DBColumn column = TestUtilsDBColumn.CreateUnsavedValidDBColumn();
            column.ColumnName = "a" + column.ColumnName;
            DBColumn column2 = TestUtilsDBColumn.CreateUnsavedValidDBColumn();
            column2.ColumnName = "b" + column2.ColumnName;
            dbPrimaryKey.AddColumnInfo(column);
            dbPrimaryKey.AddColumnInfo(column2);
            IList<DBColumn> columns = dbPrimaryKey.Columns;
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, columns.Count);
            //---------------Execute Test ----------------------
            string actualToString = dbPrimaryKey.ToString();
            //---------------Test Result -----------------------
            //            string expectedToString = dbPrimaryKey.Table.TableName + " - Primary (" + column.ColumnName + " - " + column2.ColumnName + ")";
            StringAssert.Contains(dbPrimaryKey.Table.TableName + " - Primary (", actualToString);
            StringAssert.Contains(column.ColumnName + " - " + column2.ColumnName, actualToString);
            //            Assert.AreEqual(expectedToString, actualToString);
        }

        [Test]
        public void Test_ToString_HasTwoColumns_WithReverseAlphabeticalOrder()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = TestUtilsDBPrimaryKey.CreateUnsavedValidDBPrimaryKey();
            DBColumn column = TestUtilsDBColumn.CreateUnsavedValidDBColumn();
            column.ColumnName = "b" + column.ColumnName;
            DBColumn column2 = TestUtilsDBColumn.CreateUnsavedValidDBColumn();
            column2.ColumnName = "a" + column2.ColumnName;
            dbPrimaryKey.AddColumnInfo(column);
            dbPrimaryKey.AddColumnInfo(column2);
            IList<DBColumn> columns = dbPrimaryKey.Columns;
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, columns.Count);
            //---------------Execute Test ----------------------
            string actualToString = dbPrimaryKey.ToString();
            //---------------Test Result -----------------------
            //            string expectedToString = dbPrimaryKey.Table.TableName + " - Primary (" + column.ColumnName + " - " + column2.ColumnName + ")";
            StringAssert.Contains(dbPrimaryKey.Table.TableName + " - Primary (", actualToString);
            StringAssert.Contains(column2.ColumnName + " - " + column.ColumnName, actualToString);
            //            Assert.AreEqual(expectedToString, actualToString);
        }

        [Test]
        public void TestGetColumnInfo_NullWhenNoColumnsExist()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbPrimaryKey.PrimaryKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBColumn primaryKeyDBColumn = dbPrimaryKey.GetColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(primaryKeyDBColumn);
        }

        [Test]
        public void TestGetColumnInfo_NullIfNotFound()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = firstDBColumn});

            DBColumn secondDBColumn = new DBColumn("TestColumn2");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = secondDBColumn});
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBColumn primaryKeyDBColumn = dbPrimaryKey.GetColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(primaryKeyDBColumn);
        }

        [Test]
        public void TestGetColumnInfo_FindsExistingOne()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = firstDBColumn});

            const string testcolumn2 = "TestColumn2";
            DBColumn secondDBColumn = new DBColumn(testcolumn2);
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = secondDBColumn});
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBColumn primaryKeyDBColumn = dbPrimaryKey.GetColumnInfo(testcolumn2);
            //---------------Test Result -----------------------
            Assert.IsNotNull(primaryKeyDBColumn);
            Assert.AreSame(secondDBColumn, primaryKeyDBColumn);
        }

        [Test]
        public void TestGetPrimaryKeyColumnInfo_NullWhenNoColumnsExist()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbPrimaryKey.PrimaryKeyColumns.Count);
            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbPrimaryKeyColumn);
        }

        [Test]
        public void TestGetPrimaryKeyColumnInfo_NullIfNotFound()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = firstDBColumn});

            DBColumn secondDBColumn = new DBColumn("TestColumn2");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = secondDBColumn});
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbPrimaryKeyColumn);
        }

        [Test]
        public void TestGetPrimaryKeyColumnInfo_FindsExistingOne()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = firstDBColumn});

            const string testcolumn2 = "TestColumn2";
            DBColumn secondDBColumn = new DBColumn(testcolumn2);
            dbPrimaryKey.PrimaryKeyColumns.Add(new DBPrimaryKeyColumn {Column = secondDBColumn});
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumn2);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dbPrimaryKeyColumn);
            Assert.AreSame(secondDBColumn, dbPrimaryKeyColumn.Column);
        }

        [Test]
        public void Test_AddNullColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey key = new DBPrimaryKey();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, key.PrimaryKeyColumns.Count);
            //---------------Execute Test ----------------------
            try
            {
                key.AddColumnInfo(null);
                Assert.Fail("expected Err");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("dbColumn", ex.ParamName);
            }
        }

        [Test]
        public void Test_AddColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            const string testcolumnName = "TestColumn1";
            DBColumn firstDBColumn = new DBColumn(testcolumnName);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn addedColumnKey = dbPrimaryKey.AddColumnInfo(firstDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, dbPrimaryKey.PrimaryKeyColumns.Count);
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumnName);
            Assert.AreSame(addedColumnKey, dbPrimaryKeyColumn);
            Assert.IsNotNull(dbPrimaryKeyColumn);
            Assert.AreEqual(testcolumnName, dbPrimaryKeyColumn.Column.ColumnName);
            Assert.AreSame(firstDBColumn, dbPrimaryKeyColumn.Column);
        }

        [Test]
        public void Test_AddColumnInfo_Twice()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            const string testcolumnName = "TestColumn1";
            DBColumn firstDBColumn = new DBColumn(testcolumnName);
            dbPrimaryKey.AddColumnInfo(firstDBColumn);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dbPrimaryKey.PrimaryKeyColumns.Count);
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumnName);
            Assert.IsNotNull(dbPrimaryKeyColumn);
            Assert.AreEqual(testcolumnName, dbPrimaryKeyColumn.Column.ColumnName);
            Assert.AreSame(firstDBColumn, dbPrimaryKeyColumn.Column);
            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn addedColumnKey = dbPrimaryKey.AddColumnInfo(firstDBColumn);
            //---------------Test Result -----------------------

            Assert.AreEqual(1, dbPrimaryKey.PrimaryKeyColumns.Count);
            dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumnName);
            Assert.IsNotNull(addedColumnKey);
            Assert.AreSame(addedColumnKey, dbPrimaryKeyColumn);
            Assert.AreEqual(testcolumnName, dbPrimaryKeyColumn.Column.ColumnName);
            Assert.AreSame(firstDBColumn, dbPrimaryKeyColumn.Column);
        }

        [Test]
        public void Test_Add_SecondColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();

            const string testcolumnName = "TestColumn1";
            DBColumn firstDBColumn = new DBColumn(testcolumnName);
            dbPrimaryKey.AddColumnInfo(firstDBColumn);

            const string testcolumn2 = "TestColumn2";
            DBColumn secondDBColumn = new DBColumn(testcolumn2);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBPrimaryKeyColumn addedColumnKey = dbPrimaryKey.AddColumnInfo(secondDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, dbPrimaryKey.PrimaryKeyColumns.Count);
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumnName);
            Assert.IsNotNull(addedColumnKey);
            Assert.AreNotSame(addedColumnKey, dbPrimaryKeyColumn);

            Assert.AreEqual(testcolumnName, dbPrimaryKeyColumn.Column.ColumnName);
            Assert.AreSame(firstDBColumn, dbPrimaryKeyColumn.Column);

            DBPrimaryKeyColumn dbPrimaryKeyColumnInfo2 = dbPrimaryKey.GetPrimaryKeyColumnInfo(testcolumn2);
            Assert.IsNotNull(dbPrimaryKeyColumnInfo2);
            Assert.AreSame(addedColumnKey, dbPrimaryKeyColumnInfo2);
            Assert.AreEqual(testcolumn2, dbPrimaryKeyColumnInfo2.Column.ColumnName);
            Assert.AreSame(secondDBColumn, dbPrimaryKeyColumnInfo2.Column);
        }

        [Test]
        public void Test_TableName_WhenTableNull_ShouldReturnEmptyString()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();
            //---------------Assert Precondition----------------
            Assert.IsNull(dbPrimaryKey.Table);
            //---------------Execute Test ----------------------
            var actualTableName = dbPrimaryKey.TableName;
            //---------------Test Result -----------------------
            Assert.IsEmpty(actualTableName);
        }

        [Test]
        public void Test_TableName_WhenTableSet_ShouldRetTableName()
        {
            //---------------Set up test pack-------------------
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();
            dbPrimaryKey.Table = new DBTable(GetRandomString());
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dbPrimaryKey.Table);
            //---------------Execute Test ----------------------
            var actualTableName = dbPrimaryKey.TableName;
            //---------------Test Result -----------------------
            Assert.AreEqual(dbPrimaryKey.Table.TableName, actualTableName);
        }

        private string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
    }
}